#pragma once

#include "Polynomial.h"
#include <functional>

namespace Calculus
{
    using Func11 = std::function<Real(Real)>;             // 一元函数 R -> R
    using FuncX1 = std::function<Real(LA::Vector)>;       // 多元函数 Rn -> R
    using Func1X = std::function<LA::Vector(Real)>;       // 一元向量函数 R -> Rn
    using FuncXX = std::function<LA::Vector(LA::Vector)>; // 多元向量函数 Rn -> Rm

    /**
     * @file Calculus.h
     * @author xingyifan
     * @date 2022-12-01 22:17
     *
     * @description: Jacobi 算子
     */

    class Jacobian
    {
    public:
        LA::Matrix operator()(FuncXX f, const LA::Vector &x); // 多元向量函数的 Jacobi 矩阵
        LA::Matrix operator()(FuncX1 f, const LA::Vector &x); // 多元函数的 Jacobi 矩阵
        LA::Vector operator()(Func1X f, Real x);              // 一元向量函数的导向量
        Real operator()(Func11 f, Real x);                    // 一元函数的导数
    };

    /**
     * @file Calculus.h
     * @author xingyifan
     * @date 2022-12-01 23:57
     *
     * @description: 积分器
     */

    class Integrator
    {
    protected:
        LA::Vector m_weight; // 积分权

    public:
        /**
         * @file Calculus.h
         * @author xingyifan
         * @date 2022-12-02 00:02
         *
         * @description: 初始化积分权
         */

        Integrator(int N);

        /**
         * @file Calculus.h
         * @author xingyifan
         * @date 2022-07-28 00:11
         *
         * @description: 一元函数积分
         */

        virtual Real operator()(Func11 f, Real a, Real b) = 0;

        /**
         * @file Calculus.h
         * @author xingyifan
         * @date 2022-12-01 23:43
         *
         * @description: 获得积分器的分割数
         */

        int order() const;
    };

    /**
     * @file Calculus.h
     * @author xingyifan
     * @date 2022-12-01 22:53
     *
     * @description: 牛顿积分器
     */

    class NewtonCotes : public Integrator
    {
    public:
        /**
         * @file Calculus.h
         * @author xingyifan
         * @date 2022-07-28 00:18
         *
         * @description: 在构造函数中初始化权重
         */

        NewtonCotes(int N);

        /**
         * @file Calculus.h
         * @author xingyifan
         * @date 2022-07-28 00:11
         *
         * @description: 一元函数积分
         */

        virtual Real operator()(Func11 f, Real a, Real b);
    };

    /**
     * @file Calculus.h
     * @author xingyifan
     * @date 2022-12-01 23:53
     *
     * @description: 高斯积分器
     */

    class GaussIntegrator : public Integrator
    {
    public:
        LA::Vector m_node; // 积分节点

    public:
        /**
         * @file Calculus.h
         * @author xingyifan
         * @date 2022-12-01 23:54
         *
         * @description: 构造初始化权和节点
         */

        GaussIntegrator(int N);

        /**
         * @file Calculus.h
         * @author xingyifan
         * @date 2022-12-01 23:55
         *
         * @description: 一元函数积分
         */

        virtual Real operator()(Func11 f, Real a, Real b);
    };

    /**
     * @file Calculus.h
     * @author xingyifan
     * @date 2022-12-01 22:14
     *
     * @description: 求解多元隐式方程的根
     */

    class FSolve
    {
    public:
        Real operator()(Func11 f, Real x);        // 一元函数的根
        void operator()(FuncXX f, LA::Vector &x); // 多元函数求根
    };
};